

#include "SocketEventHandlerList.hpp"
#include "cybertron/core/Log.hpp"
#include "cybertron/network/SocketEventHandler.hpp"
#include <algorithm>

CYBERTRON_BEGIN

SocketEventHandlerList::SocketEventHandlerList()
{
}

SocketEventHandlerList::~SocketEventHandlerList()
{
}

void SocketEventHandlerList::addHandler(SocketEventHandlerPtr pHandler)
{
	std::unique_lock<std::recursive_mutex> lock(mEventHandlerMutex);
	auto it = std::find(mEventHandlers.begin(), mEventHandlers.end(), pHandler);
	if (it == mEventHandlers.end())
	{
		mEventHandlers.push_back(pHandler);
	}
}

void SocketEventHandlerList::removeHandler(SocketEventHandlerPtr pHandler)
{
	auto it = std::find(mEventHandlers.begin(), mEventHandlers.end(), pHandler);
	if (it != mEventHandlers.end())
	{
		mEventHandlers.erase(it);
	}
}

bool SocketEventHandlerList::onMessage(Message& msg)
{
	HandlerArray handlerClone;
	{
		std::unique_lock<std::recursive_mutex> lock(mEventHandlerMutex);
		for (size_t i = 0; i < mEventHandlers.size(); ++i)
		{
			auto pHandler = mEventHandlers[i];
			if (pHandler->getDisposed())
			{
				mEventHandlers.erase(mEventHandlers.begin() + i);
				--i;
				continue;
			}
		}
		handlerClone = mEventHandlers;
	}

	try
	{
		for (size_t i = 0; i < handlerClone.size(); ++i)
		{
			handlerClone[i]->onMessage(msg);
		}
	}
	catch (std::exception& e)
	{
		logError("Exception onMessage: %s", e.what());
		return false;
	}
	catch (...)
	{
		logError("Exception onMessage Unknown");
		return false;
	}

	return true;
}

bool SocketEventHandlerList::onConnected()
{
	HandlerArray handlerClone;
	{
		std::unique_lock<std::recursive_mutex> lock(mEventHandlerMutex);
		for (size_t i = 0; i < mEventHandlers.size(); ++i)
		{
			auto pHandler = mEventHandlers[i];
			if (pHandler->getDisposed())
			{
				mEventHandlers.erase(mEventHandlers.begin() + i);
				--i;
				continue;
			}
		}
		handlerClone = mEventHandlers;
	}

	try
	{
		for (size_t i = 0; i < handlerClone.size(); ++i)
		{
			handlerClone[i]->onConnected();
		}
	}
	catch (std::exception& e)
	{
		logError("Exception onConnected: %s", e.what());
		return false;
	}
	catch (...)
	{
		logError("Exception onConnected Unknown");
		return false;
	}

	return true;
}

bool SocketEventHandlerList::onDisconnected()
{
	HandlerArray handlerClone;
	{
		std::unique_lock<std::recursive_mutex> lock(mEventHandlerMutex);
		for (size_t i = 0; i < mEventHandlers.size(); ++i)
		{
			auto pHandler = mEventHandlers[i];
			if (pHandler->getDisposed())
			{
				mEventHandlers.erase(mEventHandlers.begin() + i);
				--i;
				continue;
			}
		}
		handlerClone = mEventHandlers;

		mEventHandlers.clear();
	}

	try
	{
		for (size_t i = 0; i < handlerClone.size(); ++i)
		{
			handlerClone[i]->onDisconnected();
		}
	}
	catch (std::exception& e)
	{
		logError("Exception onDisconnected: %s", e.what());
		return false;
	}
	catch (...)
	{
		logError("Exception onDisconnected Unknown");
		return false;
	}

	return true;
}

CYBERTRON_END
